package com.piggy.logi.sys.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.piggy.common.core.exception.GlobalException;
import com.piggy.common.core.utils.PageUtils;
import com.piggy.common.core.web.page.PagePlus;
import com.piggy.common.core.web.page.TableDataInfo;
import com.piggy.common.satoken.utils.SecurityUtils;
import com.piggy.logi.sys.bo.LogiScheduleLogEditBo;
import com.piggy.logi.sys.bo.LogiScheduleLogQueryBo;
import com.piggy.logi.sys.domain.LogiScheduleLog;
import com.piggy.logi.sys.enums.ScheduleStatusEnum;
import com.piggy.logi.sys.mapper.LogiScheduleLogMapper;
import com.piggy.logi.sys.service.ILogiScheduleLogService;
import com.piggy.logi.sys.service.ILogiScheduleService;
import com.piggy.logi.sys.vo.LogiScheduleExtVo;
import com.piggy.logi.sys.vo.LogiScheduleLogVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Collection;
import java.util.Date;
import java.util.List;

@Slf4j
@Service
public class LogiScheduleLogServiceImpl extends ServiceImpl<LogiScheduleLogMapper, LogiScheduleLog> implements ILogiScheduleLogService {

    private final static String SCHEDULE_TEMP = "%s,装载运单：%s";
    private final static String DEPARTED_TEMP = "%s,发车【%s】，司机：%s/%s，车牌号：%s";
    private final static String ARRIVED_TEMP = "%s,到达【%s】，司机：%s/%s，车牌号：%s";
    private final static String FINISHED_TEMP = "%s,完成【%s】，司机：%s/%s，车牌号：%s";
    private final static String CANCEL_SCHEDULE_TEMP = "%s,取消调度";
    private final static String PICKUPING_TEMP = "%s,提货申请";
    private final static String UNKOWN_TEMP = "%s,为主操作,状态码 %s";
    private final static String TEMP = "车次[%s]已经[%s],司机：%s/%s，车牌号：%s";

    @Resource
    private ILogiScheduleService logiScheduleService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addLog(long scheduleId, int status) {
        LogiScheduleExtVo logiSchedule = logiScheduleService.queryById(scheduleId);
        if (logiSchedule == null) {
            throw new GlobalException("调度车次不存在");
        }
        LogiScheduleLog scheduleLog = new LogiScheduleLog();
        scheduleLog.setDeptId(SecurityUtils.getMainDeptId());
        scheduleLog.setScheduleId(scheduleId);
        scheduleLog.setScheduleNo(logiSchedule.getScheduleNo());
        scheduleLog.setLogMsg(buildLogMsg1(status, logiSchedule));
        scheduleLog.setTimeLoad(new Date());
        scheduleLog.setOperator(SecurityUtils.getUserId());
        scheduleLog.setOperatePhone(SecurityUtils.getPhone());
        scheduleLog.setScheduleStatus(status);
        save(scheduleLog);
    }

    private String buildLogMsg1(int status, LogiScheduleExtVo logiSchedule) {
        return String.format(TEMP, logiSchedule.getScheduleNo(), ScheduleStatusEnum.get(status).getInfo(), logiSchedule.getDriverVo().getDriverName(), logiSchedule.getDriverVo().getPhoneNumber(), logiSchedule.getCarVo().getLicensePlate());
    }

    private String buildLogMsg(int status, LogiScheduleExtVo logiSchedule) {
        if (status == ScheduleStatusEnum.SCHEDULED.getCode()) {
            return StrUtil.format(SCHEDULE_TEMP, logiSchedule.getDriverVo().getDriverName(), "");
        } else if (status == ScheduleStatusEnum.DEPARTED.getCode()) {
            return StrUtil.format(DEPARTED_TEMP, logiSchedule.getDriverVo().getDriverName(), logiSchedule.getDriverVo().getDriverName(),
                    logiSchedule.getDriverVo().getPhoneNumber(), logiSchedule.getCarVo().getLicensePlate());
        } else if (status == ScheduleStatusEnum.ARRIVED.getCode()) {
            return StrUtil.format(ARRIVED_TEMP, logiSchedule.getDriverVo().getDriverName(), logiSchedule.getDriverVo().getDriverName(),
                    logiSchedule.getDriverVo().getPhoneNumber(), logiSchedule.getCarVo().getLicensePlate());
        } else if (status == ScheduleStatusEnum.FINSHED.getCode()) {
            return StrUtil.format(FINISHED_TEMP, logiSchedule.getDriverVo().getDriverName(), logiSchedule.getDriverVo().getDriverName(),
                    logiSchedule.getDriverVo().getPhoneNumber(), logiSchedule.getCarVo().getLicensePlate());
        } else if (status == ScheduleStatusEnum.CANCEL_SCHEDULE.getCode()) {
            return StrUtil.format(CANCEL_SCHEDULE_TEMP, logiSchedule.getDriverVo().getDriverName());
        } else if (status == ScheduleStatusEnum.PICKUPING.getCode()) {
            return StrUtil.format(PICKUPING_TEMP, logiSchedule.getDriverVo().getDriverName());
        } else {
            return StrUtil.format(UNKOWN_TEMP, logiSchedule.getDriverVo().getDriverName(), status + "");
        }
    }

    @Override
    public List<LogiScheduleLogVo> scheduleCarLogDetail(Long scheduleId) {
        return listVo(Wrappers.<LogiScheduleLog>lambdaQuery().eq(LogiScheduleLog::getScheduleId, scheduleId).orderByAsc(LogiScheduleLog::getScheduleStatus, LogiScheduleLog::getTimeLoad), LogiScheduleLogVo.class);
    }

    @Override
    public List<LogiScheduleLogVo> scheduleCarLogDetail(String scheduleNo) {
        return listVo(Wrappers.<LogiScheduleLog>lambdaQuery().eq(LogiScheduleLog::getScheduleNo, scheduleNo), LogiScheduleLogVo.class);
    }

    @Override
    public LogiScheduleLogVo queryById(Long id) {
        return getVoById(id, LogiScheduleLogVo.class);
    }

    @Override
    public TableDataInfo<LogiScheduleLogVo> queryPageList(LogiScheduleLogQueryBo bo) {
        PagePlus<LogiScheduleLog, LogiScheduleLogVo> result = pageVo(PageUtils.buildPagePlus(false), buildQueryWrapper(bo), LogiScheduleLogVo.class);
        return PageUtils.buildDataInfo(result);
    }

    @Override
    public List<LogiScheduleLogVo> queryList(LogiScheduleLogQueryBo bo) {
        return listVo(buildQueryWrapper(bo), LogiScheduleLogVo.class);
    }

    private LambdaQueryWrapper<LogiScheduleLog> buildQueryWrapper(LogiScheduleLogQueryBo bo) {
        LambdaQueryWrapper<LogiScheduleLog> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getId() != null, LogiScheduleLog::getId, bo.getId());
        lqw.eq(bo.getDeptId() != null, LogiScheduleLog::getDeptId, bo.getDeptId());
        lqw.eq(bo.getScheduleId() != null, LogiScheduleLog::getScheduleId, bo.getScheduleId());
        lqw.eq(bo.getScheduleStatus() != null, LogiScheduleLog::getScheduleStatus, bo.getScheduleStatus());
        lqw.eq(bo.getTimeLoad() != null, LogiScheduleLog::getTimeLoad, bo.getTimeLoad());
        lqw.eq(StrUtil.isNotBlank(bo.getLogMsg()), LogiScheduleLog::getLogMsg, bo.getLogMsg());
        lqw.eq(bo.getOperator() != null, LogiScheduleLog::getOperator, bo.getOperator());
        lqw.eq(StrUtil.isNotBlank(bo.getOperatePhone()), LogiScheduleLog::getOperatePhone, bo.getOperatePhone());
        lqw.orderByDesc(LogiScheduleLog::getTimeLoad);
        return lqw;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LogiScheduleLogVo insertByAddBo(LogiScheduleLogEditBo bo) {
        LogiScheduleLog add = BeanUtil.toBean(bo, LogiScheduleLog.class);
        save(add);
        return queryById(add.getId());
    }

    @Override
    @Transactional
    public LogiScheduleLogVo updateByEditBo(LogiScheduleLogEditBo bo) {
        LogiScheduleLog update = BeanUtil.toBean(bo, LogiScheduleLog.class);
        updateById(update);
        return queryById(update.getId());
    }

    @Override
    @Transactional
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return removeByIds(ids);
    }
}
